package cn.maihe.elg.operation.service.system.impl;

import cn.maihe.elg.operation.exception.ErrorCode;
import cn.maihe.elg.operation.exception.SystemRuntimeException;
import cn.maihe.elg.operation.model.enums.RoleStatusEnum;
import cn.maihe.elg.operation.repository.entity.PermissionDO;
import cn.maihe.elg.operation.repository.entity.RoleDO;
import cn.maihe.elg.operation.repository.entity.RolePermissionDO;
import cn.maihe.elg.operation.repository.entity.UserRoleDO;
import cn.maihe.elg.operation.repository.entity.entityCustom.PermissionDOCustom;
import cn.maihe.elg.operation.repository.entity.entityCustom.RoleDOCustom;
import cn.maihe.elg.operation.repository.mapper.PermissionMapper;
import cn.maihe.elg.operation.repository.mapper.RoleMapper;
import cn.maihe.elg.operation.repository.mapper.RolePermissionMapper;
import cn.maihe.elg.operation.repository.mapper.UserRoleMapper;
import cn.maihe.elg.operation.service.system.RoleService;
import cn.maihe.elg.operation.service.system.UserService;
import cn.maihe.elg.operation.utils.IdGenerate;
import cn.maihe.elg.operation.utils.PermissionHelper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author JHWei on 2018-07-13.
 * @ 创建日期：2018-07-13
 */
@Service
@Slf4j
public class RoleServiceImpl implements RoleService {
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private PermissionMapper permissionMapper;
    @Resource
    private RolePermissionMapper rolePermissionMapper;
    @Resource
    private UserRoleMapper userRoleMapper;
    @Resource
    private UserService userService;

    @Override
    public PageInfo<RoleDOCustom> getRoles(int pageNo, int pageSize, String rolename) {
        PageHelper.startPage(pageNo, pageSize);
        List<RoleDOCustom> rolePages = roleMapper.findAll(rolename, RoleStatusEnum.NORMAL.toString());
        for (RoleDOCustom roleDO : rolePages) {
            List<PermissionDOCustom> permissionList = permissionMapper.findByRoleId(roleDO.getId());
            roleDO.setPermissionList(permissionList);
        }
        return new PageInfo<>(rolePages);
    }

    /**
     * 获取角色分页信息
     *
     * @param pageNo   页号
     * @param pageSize 每页大小
     * @param roleName
     * @param roleType 角色类型
     * @return 角色分页列表
     */
    @Override
    public PageInfo<RoleDOCustom> getRolesByType(int pageNo, int pageSize, String roleName, int roleType) {
        PageHelper.startPage(pageNo, pageSize);
        List<RoleDOCustom> rolePages = roleMapper.findByType(roleName, roleType, RoleStatusEnum.NORMAL.toString());
        return new PageInfo<>(rolePages);
    }

    @Override
    public RoleDOCustom getRole(Long id) {
        //查询当前角色id的所有信息（包括权限列表）
        RoleDOCustom role = roleMapper.selectByIdCustom(id);
        if (role == null) {
            return null;
        }
        List<PermissionDOCustom> rolePermissionList = permissionMapper.findByRoleId(role.getId());
        role.setPermissionList(rolePermissionList);
        List<Long> rolePermissions = rolePermissionList.stream().map(PermissionDO::getId).collect(Collectors.toList());
        List<Long> parentPermissionIds = rolePermissionList.stream().filter(permission -> permission.getParentId() != null).map(PermissionDO::getParentId).collect(Collectors.toList());
        //移除权限中的父节点
        rolePermissions.removeAll(parentPermissionIds);
        List<PermissionDOCustom> permissions = new ArrayList<>();
        //获取所有权限列表
        List<PermissionDOCustom> permissionList = permissionMapper.selectListAll();
        for (PermissionDOCustom permission : permissionList) {
            if (rolePermissions.contains(permission.getId())) {
                permission.setChecked(true);
                permissions.add(permission);
            } else {
                permissions.add(permission);
            }
        }
        role.setPermissionList(PermissionHelper.listToTree(permissions));
        return role;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public void saveRole(RoleDOCustom role) {
        if (role == null) {
            return;
        }
        //正常状态下的角色
        List<RoleDO> roleList = roleMapper.selectList(new EntityWrapper<RoleDO>()
                .eq("rolename", role.getRolename())
                .eq("status", RoleStatusEnum.NORMAL.toString())
        );
        if (!CollectionUtils.isEmpty(roleList)) {
            log.error("角色名称重复");
            throw new SystemRuntimeException(ErrorCode.BSMRM001, role.getRolename());
        }
        role.setGmtCreate(new Date());
        role.setUserCreate(userService.getUserContext().getUsername());
        role.setGmtModified(new Date());
        role.setUserModified(userService.getUserContext().getUsername());
        role.setId(IdGenerate.getId());
        roleMapper.insert(role);
        insertRolePerm(role);
    }

    private void insertRolePerm(RoleDOCustom role) {
        // 创建角色权限
        if (CollectionUtils.isEmpty(role.getPermissionList())) {
            log.error("权限为空");
            throw new SystemRuntimeException(ErrorCode.BSMRM002);
        }
        List<Long> permIds = new ArrayList<>();
        List<Long> parentPermIds = new ArrayList<>();
        for (PermissionDO permissionDOCustom : role.getPermissionList()) {
            permIds.add(permissionDOCustom.getId());
            if (permissionDOCustom.getParentId() != null) {
                parentPermIds.add(permissionDOCustom.getParentId());
            }
        }
        parentPermIds.add(1L);
//        List<Long> permIds = role.getPermissionList()
//                .stream()
//                .map(PermissionDO::getId)
//                .collect(Collectors.toList());
//        List<Long> parentPermIds = role
//                .getPermissionList()
//                .stream()
//                .filter(item -> item
//                        .getParentId() != null)
//                .map(PermissionDO::getParentId)
//                .collect(Collectors.toList());
        permIds.addAll(parentPermIds);
        permIds = permIds
                .parallelStream()
                .distinct()
                .collect(Collectors.toList());
        List<RolePermissionDO> list = new ArrayList<>();
        for (int i = 0; i < permIds.size(); i++) {
            RolePermissionDO tempR = new RolePermissionDO();
            tempR.setPermissionId(permIds.get(i));
            tempR.setRoleId(role.getId());
            list.add(tempR);
        }
        rolePermissionMapper.insertRolePermission(list);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public void updateRole(RoleDOCustom role) {
        if (role == null) {
            return;
        }
        // 判断角色名称是否重复
        List<RoleDO> roleList = roleMapper.selectList(new EntityWrapper<RoleDO>()
                .eq("rolename", role.getRolename())
                .eq("status", RoleStatusEnum.NORMAL.toString())
                .ne("id", role.getId())
        );
        if (!CollectionUtils.isEmpty(roleList)) {
            log.error("角色名称重复");
            throw new SystemRuntimeException(ErrorCode.BSMRM001, role.getRolename());
        }
        if (CollectionUtils.isEmpty(role.getPermissionList())) {
            log.error("角色的权限不能为空");
            throw new SystemRuntimeException(ErrorCode.BSMRM002);
        }
        RoleDO tempRole = new RoleDO();
        tempRole.setId(role.getId());
        tempRole.setRolename(role.getRolename());
        tempRole.setType(role.getType());
        tempRole.setGmtModified(new Date());
        tempRole.setUserModified(userService.getUserContext().getUsername());
        roleMapper.updateById(tempRole);
        rolePermissionMapper.delete(new EntityWrapper<RolePermissionDO>().eq("role_id", role.getId()));
        insertRolePerm(role);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public void deleteRole(Long id) {
        //查询该角色是正在被使用
        int count = userRoleMapper.selectCount(new EntityWrapper<UserRoleDO>().eq("role_id", id));
        if (count > 0) {
            log.error("该角色正在使用");
            throw new SystemRuntimeException(ErrorCode.BSMRM003);
        }
        rolePermissionMapper.delete(new EntityWrapper<RolePermissionDO>().eq("role_id", id));
        roleMapper.deleteById(id);
    }

    @Override
    public List<RoleDOCustom> getRoles() {
        return roleMapper.findAll(null, RoleStatusEnum.NORMAL.toString());
    }

}
